home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / FGL304B.ZIP;1 / MANUALS.ARJ / USER05.DOC < prev    next >
Encoding:
Text File  |  1994-01-24  |  71.6 KB  |  1,583 lines

  1. Chapter 5
  2.  
  3.  
  4.  
  5.  
  6.  
  7. The Use of Color
  8.  
  9. 68   Fastgraph User's Guide
  10.  
  11.  
  12. Overview
  13.  
  14.      The use of color is an important part of any text or graphics
  15. application.  This chapter explains color as it applies to text and graphics
  16. modes.  It also describes palettes and video DAC registers for the graphics
  17. video modes that offer this functionality.  Finally, an explanation of
  18. Fastgraph's virtual colors is provided.
  19.  
  20.  
  21. Text Modes
  22.  
  23.      The term color is not really correct in text modes because each
  24. character cell has an associated attribute that controls the character's
  25. appearance in that cell.  The meaning of the attribute differs for color and
  26. monochrome text modes.
  27.  
  28.  
  29. Color Text Modes
  30.  
  31.      In color text modes (modes 0, 1, 2, and 3), the attribute determines a
  32. character's foreground color (the color of the character itself), its
  33. background color (the color of that part of the character cell not covered by
  34. the character), and whether or not it blinks.  Sixteen foreground colors
  35. (numbered 0 to 15) are available, but only eight background colors (numbered
  36. 0 to 7) are available.  The colors assigned to these values are listed in the
  37. following table.
  38.  
  39.                          number  color     number    color
  40.  
  41.                            0     black       8     dark gray
  42.                            1     blue        9    light blue
  43.                            2     green       10   light green
  44.                            3     cyan        11   light cyan
  45.                            4      red        12    light red
  46.                            5    magenta      13  light magenta
  47.                            6     brown       14     yellow
  48.                            7     gray        15      white
  49.  
  50. At first it may seem the numbers have been arbitrarily assigned to the
  51. colors.  Upon further inspection, however, it becomes apparent this is not
  52. the case.  Each color number is a four bit quantity of the form IRGB, with I
  53. representing the intensity, R the red component, G the green component, and B
  54. the blue component.  If the corresponding bit is 1, it means the intensity or
  55. color component is set.  For example, normal red would be represented by the
  56. IRGB bit pattern 0100, which is 4 decimal, the color number for red.
  57.  
  58.      The fg_setattr routine defines the current text attribute.  Once
  59. fg_setattr is called, Fastgraph displays all subsequent text using that
  60. attribute.  The first argument of fg_setattr defines the foreground color,
  61. which must be an integer between 0 and 15.  Its second argument defines the
  62. background color, which must be between 0 and 7.  Its third argument
  63. determines if the foreground color blinks (1 means it blinks, 0 means it does
  64. not).  For example, the statement
  65.  
  66.                              fg_setattr(14,1,0);
  67.  
  68.                                              Chapter 5:  The Use of Color   69
  69.  
  70.  
  71. specifies subsequent text will be displayed with a yellow foreground (14) on
  72. a blue background (1) and will not blink (0).
  73.  
  74.      Another Fastgraph routine, fg_setcolor, also can define text attributes.
  75. The fg_setcolor routine packs the three values passed to fg_setattr into a
  76. single argument, as shown below.
  77.  
  78.                          bits      attribute
  79.  
  80.                          0-3       foreground color
  81.                          4-6       background color
  82.                          7         blinking
  83.  
  84. For example, calling fg_setcolor with an argument of 30 (1E hex) is
  85. equivalent to calling fg_setattr with arguments of 14, 1, and 0.
  86.  
  87.      The Fastgraph routine fg_getcolor returns the current text attribute, as
  88. defined in the most recent call to fg_setattr or fg_setcolor.  The
  89. fg_getcolor routine has no arguments and returns the attribute as its
  90. function value.  The returned value is encoded using the same scheme for
  91. passing a text attribute to the fg_setcolor routine.
  92.  
  93.  
  94. Monochrome Text Mode
  95.  
  96.      In the monochrome text mode (mode 7), colors are obviously not
  97. available.  The attribute instead determines whether a character is
  98. invisible, normal, bold, reversed, or certain combinations of these.  The
  99. following table shows the values assigned to the available display
  100. characteristics.
  101.  
  102.                     foreground  background  characteristic
  103.  
  104.                     0           0           invisible
  105.                     0           7           reversed
  106.                     1           0           underlined
  107.                     7           0           normal
  108.                     9           0           underlined bold
  109.                     15          0           bold
  110.  
  111. Additionally, you can turn blinking on or off for each of these combinations.
  112. Any combination of foreground and background values not listed in the above
  113. table produces a normal display characteristic.
  114.  
  115.      As in the color modes, the Fastgraph routines fg_setattr and fg_setcolor
  116. define the current text attribute.  For example, the statement
  117.  
  118.                               fg_setattr(0,7,1);
  119.  
  120. specifies subsequent text will be displayed in reverse video (0,7) and will
  121. blink (1).  The same attribute could be defined by calling fg_setcolor with
  122. an argument of 240 (F0 hex).  The fg_getcolor routine is also available and
  123. works as it does in the color text modes.
  124. 70   Fastgraph User's Guide
  125.  
  126.  
  127.  
  128. Graphics Modes
  129.  
  130.      In graphics modes, each pixel has an associated color value that
  131. determines the color in which the pixel is displayed.  The number of
  132. available colors depends on the video mode.  Some of the graphics modes also
  133. have palette registers or video DAC registers to provide additional color
  134. capabilities.  The example programs presented in this section show the use of
  135. color in specific graphics video modes.
  136.  
  137.      The following subsections will discuss the use of color in each graphics
  138. video mode.  In these discussions, there will be several references to a
  139. group of colors called the standard color set.  This is a set of 16 colors
  140. common to many of the graphics video modes (and to the color text modes).
  141. The colors in the standard color set are listed in the following table.
  142.  
  143.                          number  color     number    color
  144.  
  145.                            0     black       8     dark gray
  146.                            1     blue        9    light blue
  147.                            2     green       10   light green
  148.                            3     cyan        11   light cyan
  149.                            4      red        12    light red
  150.                            5    magenta      13  light magenta
  151.                            6     brown       14     yellow
  152.                            7     gray        15      white
  153.  
  154.      At this point it is important to understand the difference between the
  155. terms color number and color value.  Color number refers to the number that
  156. defines a color in the standard color set (for example, green is color number
  157. 2).  Color value refers to the actual value of a pixel in video memory, which
  158. ultimately determines the color in which that pixel is displayed.  The color
  159. value is sometimes just called the color.
  160.  
  161.      In each graphics mode, video memory is cleared when the fg_setmode
  162. routine is called.  This means all pixels are initially set to color value 0,
  163. which by default is black.  For this reason, color value 0 is often called
  164. the background color in graphics video modes.
  165.  
  166.      The Fastgraph routine fg_setcolor defines the color in which subsequent
  167. graphics operations are performed.  This color is called the current color.
  168. Depending on the video mode, the current color can reference a color value
  169. (in CGA and Hercules graphics modes), a palette register (in Tandy, EGA, and
  170. VGA graphics modes), or a video DAC register (in 256-color modes).  The
  171. fg_setcolor routine takes a single integer argument that specifies the color.
  172. When fg_setmode is called, it sets the current color to 0.  The Fastgraph
  173. routine fg_getcolor returns the current color, as defined in the most recent
  174. call to fg_setcolor.  The fg_getcolor routine has no arguments and returns
  175. the current color as its function value.
  176.  
  177.  
  178. CGA Color Modes
  179.  
  180.      The CGA color modes (modes 4 and 5) have six sets of available colors,
  181. called palettes, numbered 0 to 5.  Each palette consists of four colors,
  182. numbered 0 to 3.  In each palette, the background color (color value 0) can
  183.                                              Chapter 5:  The Use of Color   71
  184.  
  185.  
  186. be selected from the standard color set, but the other 3 colors are fixed.
  187. The following table shows the fixed colors assigned to each palette.
  188.  
  189.                      palette 0       palette 1       palette 2
  190.  
  191.            color 1   light green     light cyan      light cyan
  192.            color 2   light red       light magenta   light red
  193.            color 3   yellow          white           white
  194.  
  195.                      palette 3       palette 4       palette 5
  196.  
  197.            color 1   green           cyan            cyan
  198.            color 2   red             magenta         red
  199.            color 3   brown           gray            gray
  200.  
  201. Palette 1, with a black background, is the default palette when you select
  202. mode 4.  Palette 2, with a black background, is the default palette when you
  203. select mode 5.
  204.  
  205.      The CGA color modes have a border area called the overscan between the
  206. addressable pixel space and the physical edges of the screen.  The overscan
  207. area is always displayed in the background color, regardless of which CGA
  208. palette is used.
  209.  
  210.      In CGA color modes, the fg_setcolor routine defines the current color by
  211. referencing one of the four color values.  The fg_palette routine selects one
  212. of the six palettes and defines the background color for that palette.  The
  213. first argument of the fg_palette routine is an integer between 0 and 5 that
  214. specifies the palette number.  The second argument is an integer between 0
  215. and 15 that defines the background color, using the color numbers in the
  216. standard color set.
  217.  
  218.      Example 5-1 demonstrates the use of the fg_palette and fg_setcolor
  219. routines in mode 4.  After establishing the video mode, the program selects
  220. palette 0 and makes the background color blue (color number 1).  It then
  221. makes color 3 in palette 0 (yellow) the current color and displays the word
  222. "Hello".  Finally, it restores the original video mode and screen attributes
  223. before returning to DOS.
  224.  
  225.                                  Example 5-1.
  226.  
  227.                            #include <fastgraf.h>
  228.                            void main(void);
  229.  
  230.                            void main()
  231.                            {
  232.                               int mode;
  233.  
  234.                               mode = fg_getmode();
  235.                               fg_setmode(4);
  236.  
  237.                               fg_palette(0,1);
  238.                               fg_setcolor(3);
  239.                               fg_text("Hello",5);
  240.                               fg_waitkey();
  241.  
  242. 72   Fastgraph User's Guide
  243.  
  244.  
  245.  
  246.                               fg_setmode(mode);
  247.                               fg_reset();
  248.                            }
  249.  
  250.  
  251.  
  252. CGA Two-Color Mode
  253.  
  254.      The CGA two-color mode (mode 6) has a fixed background color (color
  255. value 0) and a user-definable foreground color (color value 1).  The
  256. background color is always black.  The foreground color is white by default,
  257. but it can be changed to any of the colors in the standard color set.  It
  258. should be mentioned that changing the foreground color works on true CGA
  259. adapters, but there are very few EGA and VGA adapters that correctly
  260. implement changing the foreground color in their mode 6 emulation.
  261.  
  262.      In mode 6, the fg_setcolor routine defines the current color by
  263. referencing one of the two color values.  The fg_palette routine defines the
  264. actual foreground color (that is, the color of pixels whose color value is
  265. 1).  For consistency with other graphics modes, the fg_palette routine has
  266. two arguments, but the first one is not used.  The second argument is an
  267. integer between 0 and 15 that defines the foreground color, using the color
  268. numbers in the standard color set.
  269.  
  270.      Example 5-2 demonstrates the use of the fg_palette and fg_setcolor
  271. routines in mode 6.  After establishing the video mode, the program makes the
  272. foreground color yellow (color number 14).  It then makes color 1 the current
  273. color and displays the word "Hello".  Finally, it restores the original video
  274. mode and screen attributes before returning to DOS.
  275.  
  276.                                  Example 5-2.
  277.  
  278.                            #include <fastgraf.h>
  279.                            void main(void);
  280.  
  281.                            void main()
  282.                            {
  283.                               int mode;
  284.  
  285.                               mode = fg_getmode();
  286.                               fg_setmode(6);
  287.  
  288.                               fg_palette(0,14);
  289.                               fg_setcolor(1);
  290.                               fg_text("Hello",5);
  291.                               fg_waitkey();
  292.  
  293.                               fg_setmode(mode);
  294.                               fg_reset();
  295.                            }
  296.  
  297.                                              Chapter 5:  The Use of Color   73
  298.  
  299.  
  300. Tandy and PCjr Modes
  301.  
  302.      The supported Tandy 1000 or PCjr graphics mode (mode 9) has 16 color
  303. values, numbered 0 to 15.  Each color value references one of 16 user-
  304. definable palette registers, often simply called palettes, also numbered 0 to
  305. 15.  The values assigned to the palette registers determine the colors in
  306. which pixels are displayed.  For example, if you assign palette register 2
  307. the value for red, then pixels whose color value is 2 will be red.
  308.  
  309.      Each palette can assume one of the 16 colors in the standard color set.
  310. By default, the values assigned to the 16 palettes correspond to the
  311. identically numbered colors in the standard color set.  In other words,
  312. palette 0 is assigned the value for black, palette 1 is assigned the value
  313. for blue, and so forth.
  314.  
  315.      In mode 9, the fg_setcolor routine defines the current color by
  316. referencing one of the 16 palette registers.  The fg_palette routine defines
  317. the actual color assigned to a specific palette register.  The first argument
  318. of the fg_palette routine is an integer between 0 and 15 that specifies the
  319. palette number.  The second argument is an integer between 0 and 15 that
  320. defines the palette value (the color assigned to the palette), using the IRGB
  321. color numbers in the standard color set.
  322.  
  323.      You also can use the Fastgraph routine fg_setrgb to define the color
  324. assigned to a specific palette register.  Whereas the fg_palette routine does
  325. this using a color number from the standard color set, fg_setrgb defines a
  326. palette register using red, green, and blue color components plus an
  327. intensity component.  The first argument of the fg_setrgb routine is an
  328. integer between 0 and 15 that specifies the palette register number.  The
  329. remaining three arguments are each integer values between -1 and 1 that
  330. respectively specify the red, green, and blue color components for that
  331. palette register.  The meanings of the color components are:
  332.  
  333.      -1 = color bit and intensity bit are set
  334.       0 = color bit is reset
  335.       1 = color bit is set
  336.  
  337. Since there is only one intensity bit in mode 9 color values, specifying -1
  338. for any of the RGB color components produces an intense color.  For example,
  339. the color light cyan is color number 11 in the standard color set, and it is
  340. produced by combining green and blue and setting the intensity bit.  This
  341. means any of these four statements
  342.  
  343.                             fg_palette(1,11);
  344.                             fg_setrgb(1,0,-1,1);
  345.                             fg_setrgb(1,0,1,-1);
  346.                             fg_setrgb(1,0,-1,-1);
  347.  
  348. could be used to define palette register 1 as light cyan in mode 9.
  349.  
  350.      Example 5-3 demonstrates the use of the fg_palette and fg_setcolor
  351. routines in mode 9.  After establishing the video mode, the program defines
  352. palette 0 to be blue (1) and palette 1 to be yellow (14).  Note that defining
  353. palette 0 changes the background color.  It then makes color 1 the current
  354. 74   Fastgraph User's Guide
  355.  
  356.  
  357. color and displays the word "Hello".  After waiting for a keystroke, the
  358. program changes the color of "Hello" by changing palette 1 to white (15).
  359. Finally, it restores the original video mode and screen attributes before
  360. returning to DOS.
  361.  
  362.                                  Example 5-3.
  363.  
  364.                            #include <fastgraf.h>
  365.                            void main(void);
  366.  
  367.                            void main()
  368.                            {
  369.                               int mode;
  370.  
  371.                               mode = fg_getmode();
  372.                               fg_setmode(9);
  373.  
  374.                               fg_palette(0,1);
  375.                               fg_palette(1,14);
  376.  
  377.                               fg_setcolor(1);
  378.                               fg_text("Hello",5);
  379.                               fg_waitkey();
  380.  
  381.                               fg_palette(1,15);
  382.                               fg_waitkey();
  383.  
  384.                               fg_setmode(mode);
  385.                               fg_reset();
  386.                            }
  387.  
  388.  
  389. Hercules Mode
  390.  
  391.      The Hercules graphics mode (mode 11) has a fixed background color (color
  392. value 0) and a fixed foreground color (color value 1).  The background color
  393. is always black, and the foreground color is dependent on the monochrome
  394. display being used (typically it is green, amber, or white).
  395.  
  396.      The fg_setcolor routine defines the current color value by referencing
  397. one of the two color values.  The fg_palette routine has no effect in mode
  398. 11.
  399.  
  400.      Example 5-4 demonstrates the use of the fg_setcolor routine in mode 11.
  401. After establishing the video mode, the program makes color 1 the current
  402. color and displays the word "Hello".  It then restores the original video
  403. mode and screen attributes before returning to DOS.
  404.  
  405.                                  Example 5-4.
  406.  
  407.                            #include <fastgraf.h>
  408.                            void main(void);
  409.  
  410.                            void main()
  411.                            {
  412.                               int mode;
  413.  
  414.                                              Chapter 5:  The Use of Color   75
  415.  
  416.  
  417.  
  418.                               mode = fg_getmode();
  419.                               fg_setmode(11);
  420.  
  421.                               fg_setcolor(1);
  422.                               fg_text("Hello",5);
  423.                               fg_waitkey();
  424.  
  425.                               fg_setmode(mode);
  426.                               fg_reset();
  427.                            }
  428.  
  429.  
  430.  
  431. Hercules Low-Resolution Mode
  432.  
  433.      The Hercules low-resolution graphics mode (mode 12) has four color
  434. values, numbered 0 to 3.  The background color is always black, colors 1 and
  435. 2 are half intensity, and color 3 is full intensity.  Colors 1 and 2 both
  436. produce normal intensity colors, but they do so with different pixel
  437. patterns -- color 1 turns on the odd-numbered physical pixels, while color 2
  438. turns on the even-numbered physical pixels.  The appearance of colors 1 to 3
  439. is dependent on the monochrome display being used (typically it is green,
  440. amber, or white).
  441.  
  442.      The fg_setcolor routine defines the current color value by referencing
  443. one of the four color values.  The fg_palette routine has no effect in mode
  444. 12.
  445.  
  446.      Example 5-5 demonstrates the use of the fg_setcolor routine in mode 12.
  447. After establishing the video mode, the program makes color 3 the current
  448. color and displays the word "Hello".  It then restores the original video
  449. mode and screen attributes before returning to DOS.
  450.  
  451.                                  Example 5-5.
  452.  
  453.                            #include <fastgraf.h>
  454.                            void main(void);
  455.  
  456.                            void main()
  457.                            {
  458.                               int mode;
  459.  
  460.                               mode = fg_getmode();
  461.                               fg_setmode(12);
  462.  
  463.                               fg_setcolor(3);
  464.                               fg_text("Hello",5);
  465.                               fg_waitkey();
  466.  
  467.                               fg_setmode(mode);
  468.                               fg_reset();
  469.                            }
  470.  
  471. 76   Fastgraph User's Guide
  472.  
  473.  
  474.  
  475. EGA 200-Line Modes
  476.  
  477.      The 200-line EGA graphics modes (modes 13 and 14) have 16 color values,
  478. numbered 0 to 15.  Each color value references one of 16 user-definable
  479. palette registers, often simply called palettes, also numbered 0 to 15.  The
  480. values assigned to the palette registers determine the colors in which pixels
  481. are displayed.  For example, if you assign palette register 2 the value for
  482. red, then pixels whose color value is 2 will be red.
  483.  
  484.      Each palette can assume one of the 16 colors in the standard color set.
  485. By default, the values assigned to the 16 palettes correspond to the
  486. identically numbered colors in the standard color set.  In other words,
  487. palette 0 is assigned the value for black, palette 1 is assigned the value
  488. for blue, and so forth.
  489.  
  490.      In modes 13 and 14, the fg_setcolor routine defines the current color by
  491. referencing one of 16 available palette registers.  The fg_palette routine
  492. defines the actual color assigned to a specific palette register.  The first
  493. argument of the fg_palette routine is an integer between 0 and 15 that
  494. specifies the palette number.  The second argument is an integer that defines
  495. the palette value (the color assigned to the palette).  Although the actual
  496. colors are taken from the standard color set, the binary structure of a
  497. palette value is different from the IRGB format used in the standard color
  498. set.  In modes 13 and 14, the binary structure of a palette value is IxRGB;
  499. bit 3 is ignored.  The mode 13 and mode 14 palette values that correspond to
  500. the standard color set are thus:
  501.  
  502.                          value   color     value     color
  503.  
  504.                            0     black       16    dark gray
  505.                            1     blue        17   light blue
  506.                            2     green       18   light green
  507.                            3     cyan        19   light cyan
  508.                            4      red        20    light red
  509.                            5    magenta      21  light magenta
  510.                            6     brown       22     yellow
  511.                            7     gray        23      white
  512.  
  513.      You also can use the Fastgraph routine fg_setrgb to define the color
  514. assigned to a specific palette register.  Whereas the fg_palette routine does
  515. this using a color number from the standard color set, fg_setrgb defines a
  516. palette register using red, green, and blue color components, plus an
  517. intensity component.  The first argument of the fg_setrgb routine is an
  518. integer between 0 and 15 that specifies the palette register number.  The
  519. remaining three arguments are each integer values between -1 and 1 that
  520. respectively specify the red, green, and blue color components for that
  521. palette register.  The meanings of the color components are:
  522.  
  523.      -1 = color bit and intensity bit are set
  524.       0 = color bit is reset
  525.       1 = color bit is set
  526.  
  527. Since there is only one intensity bit in mode 13 and 14 color values,
  528. specifying -1 for any of the RGB color components produces an intense color.
  529. For example, the color light cyan is represented by the color value 19, and
  530.                                              Chapter 5:  The Use of Color   77
  531.  
  532.  
  533. it is produced by combining green and blue and setting the intensity bit.
  534. This means any of these four statements
  535.  
  536.  
  537.                             fg_palette(1,19);
  538.                             fg_setrgb(1,0,-1,1);
  539.                             fg_setrgb(1,0,1,-1);
  540.                             fg_setrgb(1,0,-1,-1);
  541.  
  542.  
  543. could be used to define palette register 1 as light cyan in modes 13 and 14.
  544.  
  545.      The Fastgraph routine fg_setcolor defines the color value (that is, the
  546. palette number) in which subsequent graphics operations are performed.  The
  547. fg_setcolor routine takes a single integer argument that specifies this
  548. color.  When fg_setmode is called, it sets the color value to 0.  The
  549. Fastgraph routine fg_getcolor returns the current color value, as defined in
  550. the most recent call to fg_setcolor.  The fg_getcolor routine has no
  551. arguments and returns the current color as the function value.
  552.  
  553.      Example 5-6 demonstrates the use of the fg_palette and fg_setcolor
  554. routines in mode 13.  After establishing the video mode, the program defines
  555. palette 0 to be blue (1) and palette 1 to be yellow (22).  Note that defining
  556. palette 0 changes the background color.  It then makes color 1 the current
  557. color and displays the word "Hello".  After waiting for a keystroke, the
  558. program changes the color of "Hello" by changing palette 1 to white (23).
  559. Finally, it restores the original video mode and screen attributes before
  560. returning to DOS.
  561.  
  562.                                  Example 5-6.
  563.  
  564.                            #include <fastgraf.h>
  565.                            void main(void);
  566.  
  567.                            void main()
  568.                            {
  569.                               int mode;
  570.  
  571.                               mode = fg_getmode();
  572.                               fg_setmode(13);
  573.  
  574.                               fg_palette(0,1);
  575.                               fg_palette(1,22);
  576.  
  577.                               fg_setcolor(1);
  578.                               fg_text("Hello",5);
  579.                               fg_waitkey();
  580.  
  581.                               fg_palette(1,23);
  582.                               fg_waitkey();
  583.  
  584.                               fg_setmode(mode);
  585.                               fg_reset();
  586.                            }
  587.  
  588. 78   Fastgraph User's Guide
  589.  
  590.  
  591. EGA Monochrome Mode
  592.  
  593.      The EGA monochrome graphics mode (mode 15) assigns display attributes to
  594. its four color values, numbered 0 to 3.  Each color value references one of
  595. four user-definable palette registers, often simply called palettes, numbered
  596. 0, 1, 4, and 5.  This strange numbering results from the disabling of two of
  597. the four video memory bit planes in mode 15.  The values assigned to the
  598. palette registers determine the pixel display attribute.  For example, if you
  599. assign palette register 1 the value for bold, then pixels whose value is 1
  600. will be bold.
  601.  
  602.      In mode 15, the fg_setcolor routine defines the current color (actually,
  603. a display attribute) by referencing one of the four palette registers.  The
  604. fg_palette routine defines the actual display attribute assigned to a
  605. specific palette register.  The first argument of the fg_palette routine is
  606. an integer that specifies the palette number.  The second argument is an
  607. integer that defines the palette value (the display attribute assigned to the
  608. palette).  For each palette register, the following table shows the default
  609. palette value and its associated display attribute.
  610.  
  611.                       palette   palette   display
  612.                       number     value   attribute
  613.  
  614.                          0         0     invisible
  615.                          1         8      normal
  616.                          4        24       bold
  617.                          5        24       bold
  618.  
  619.      Example 5-7 demonstrates the use of the fg_palette and fg_setcolor
  620. routines in mode 15.  After establishing the video mode, the program makes
  621. color 4 (actually, palette 4, which is bold by default) the current color and
  622. displays the word "Hello".  After waiting for a keystroke, the program
  623. changes the display attribute of "Hello" by changing palette 4 to normal
  624. intensity (palette value 8).  Finally, it restores the original video mode
  625. and screen attributes before returning to DOS.
  626.  
  627.                                  Example 5-7.
  628.  
  629.                            #include <fastgraf.h>
  630.                            void main(void);
  631.  
  632.                            void main()
  633.                            {
  634.                               int mode;
  635.  
  636.                               mode = fg_getmode();
  637.                               fg_setmode(15);
  638.  
  639.                               fg_setcolor(4);
  640.                               fg_text("Hello",5);
  641.                               fg_waitkey();
  642.  
  643.                               fg_palette(4,8);
  644.                               fg_waitkey();
  645.  
  646.                               fg_setmode(mode);
  647.                                              Chapter 5:  The Use of Color   79
  648.  
  649.  
  650.                               fg_reset();
  651.                            }
  652.  
  653.  
  654. EGA Enhanced Mode
  655.  
  656.      The EGA enhanced graphics mode (mode 16) has 16 color values, numbered 0
  657. to 15.  Each color value references one of 16 user-definable palette
  658. registers, often simply called palettes, also numbered 0 to 15.  The values
  659. assigned to the palette registers determine the colors in which pixels are
  660. displayed.  For example, if you assign palette register 2 the value for red,
  661. then pixels whose color value is 2 will be red.
  662.  
  663.      Each palette can assume one of 64 available colors.  By default, the
  664. values assigned to the 16 palettes correspond to the identically numbered
  665. colors in the standard color set.  In other words, palette 0 is assigned the
  666. value for black, palette 1 is assigned the value for blue, and so forth.
  667. There are a few EGA-compatible adapters that do not properly assign the
  668. default colors to the 16 palette registers, so it is a good practice to do
  669. this explicitly in mode 16.
  670.  
  671.      In mode 16, the fg_setcolor routine defines the current color value by
  672. referencing one of the 16 palette registers.  The fg_palette routine defines
  673. the actual color assigned to a specific palette register.  The first argument
  674. of the fg_palette routine is an integer between 0 and 15 that specifies the
  675. palette number.  The second argument is an integer that defines the palette
  676. value (the color assigned to the palette).  The binary structure of a palette
  677. value is different from the IRGB format used in the standard color set.  In
  678. mode 16, the binary structure of a palette value is a 6-bit quantity of the
  679. form rgbRGB, where the lower case letters represent the low intensity (1/3
  680. intensity) color components, and the upper case letters represent the normal
  681. intensity (2/3 intensity) color components.  The mode 16 palette values that
  682. correspond to the standard color set are:
  683.  
  684.                          value   color     value     color
  685.  
  686.                            0     black       56    dark gray
  687.                            1     blue        57   light blue
  688.                            2     green       58   light green
  689.                            3     cyan        59   light cyan
  690.                            4      red        60    light red
  691.                            5    magenta      61  light magenta
  692.                            20    brown       62     yellow
  693.                            7     gray        63      white
  694.  
  695.      The normal intensity components in mode 16 produce the same normal
  696. intensity colors as in other 16-color graphics modes.  Similarly, combining
  697. the low and normal intensities in mode 16 produces the high intensity colors
  698. of the other modes.  The only exception to this is for the default brown,
  699. formed from the bit pattern 010100 (20 decimal).  This value produces a more
  700. true brown than the value 6 decimal, which is really an olive green.
  701.  
  702.      The palette values used in mode 16 are 6-bit quantities, which means
  703. there are 64 different colors available in mode 16.  This group of 64 colors
  704. consists of the 16 colors in the standard color set plus 48 additional colors
  705. that are not available in any of the other EGA modes.  However, because the
  706. 80   Fastgraph User's Guide
  707.  
  708.  
  709. EGA palette registers hold 4-bit quantities, only 16 of these colors can be
  710. displayed at the same time.  In other words, the EGA enhanced mode provides
  711. the capability of displaying 16 simultaneous colors from a group of 64.
  712.  
  713.      You also can use the Fastgraph routine fg_setrgb to define the color
  714. assigned to a specific palette register.  Whereas the fg_palette routine does
  715. this using a value between 0 and 63, fg_setrgb defines a palette register
  716. using red, green, and blue color components.  The first argument of the
  717. fg_setrgb routine is an integer between 0 and 15 that specifies the palette
  718. register number.  The remaining three arguments are each integer values
  719. between 0 and 3 that respectively specify the intensities in thirds of the
  720. red, green, and blue color components for that palette register.  For
  721. example, the color cyan is represented by the value 3 in the above table, and
  722. it is produced by combining normal intensity (2/3 intensity) green and blue.
  723. This means either of the statements
  724.  
  725.                              fg_palette(1,3);
  726.                              fg_setrgb(1,0,2,2);
  727.  
  728. could be used to define palette register 1 as cyan.
  729.  
  730.      Example 5-8 demonstrates the use of the fg_palette and fg_setcolor
  731. routines in mode 16.  It uses the Fastgraph routine fg_rect (discussed in the
  732. next chapter) to draw rectangles of a specified size.  After establishing the
  733. video mode, the program uses a for loop to draw 16 equal-size rectangles, one
  734. in each of the 16 color values.  In the same loop, the program uses the
  735. fg_palette routine to change each palette to black.  The while loop that
  736. follows performs four iterations.  The first iteration changes palette 0 to
  737. 0, palette 1 to 1, and so forth.  Hence, the 16 rectangles appear in the
  738. palette values 0 to 15.  The rectangles remain in these colors until is key
  739. is pressed to begin the next iteration.  The second iteration changes palette
  740. 0 to 16, palette 1 to 17, and so forth.  This makes the 16 rectangles appear
  741. in the palette values 16 to 31.  Iterations three and four are similar, so
  742. the overall effect of the program is to display all 64 colors, 16 at a time.
  743. Finally, the program restores the original video mode and screen attributes
  744. before returning to DOS.
  745.  
  746.                                  Example 5-8.
  747.  
  748.                 #include <fastgraf.h>
  749.                 void main(void);
  750.  
  751.                 #define COLORS 16
  752.                 #define WIDTH  40
  753.  
  754.                 void main()
  755.                 {
  756.                    int base;
  757.                    int color;
  758.                    int minx, maxx;
  759.                    int mode;
  760.  
  761.                    mode = fg_getmode();
  762.                    fg_setmode(16);
  763.  
  764.                                              Chapter 5:  The Use of Color   81
  765.  
  766.  
  767.                    base = 0;
  768.                    minx = 0;
  769.                    maxx = WIDTH - 1;
  770.  
  771.                    for (color = 0; color < COLORS; color++) {
  772.                       fg_palette(color,0);
  773.                       fg_setcolor(color);
  774.                       fg_rect(minx,maxx,0,349);
  775.                       minx = maxx + 1;
  776.                       maxx = maxx + WIDTH;
  777.                       }
  778.  
  779.                    while (base < COLORS*4) {
  780.                       for (color = 0; color < COLORS; color++)
  781.                          fg_palette(color,base+color);
  782.                       base += COLORS;
  783.                       fg_waitkey();
  784.                       }
  785.  
  786.                    fg_setmode(mode);
  787.                    fg_reset();
  788.                 }
  789.  
  790.  
  791.  
  792. VGA and MCGA Two-Color Mode
  793.  
  794.      The VGA and MCGA two-color mode (mode 17) has a background color (color
  795. value 0) and a foreground color (color value 1).  Each color value references
  796. one of two user-definable palette registers, often simply called palettes,
  797. also numbered 0 and 1.  Each palette register in turn references one of 16
  798. user-definable 18-bit video DAC registers, numbered 0 to 15.  The values
  799. assigned to the palette registers and video DAC registers determine the
  800. colors in which pixels are displayed.  For example, if palette register 1
  801. contains the value 3, and video DAC register 3 contains the color value for
  802. red, then pixels whose color value is 1 (that is, the foreground pixels) will
  803. be red.
  804.  
  805.      By default, palette register 0 references video DAC register 0, and
  806. palette register 1 references video DAC register 1.  In addition, video DAC
  807. register 0 initially contains the color value for black, while the other 15
  808. video DAC registers (1 through 15) contain the color value for white.  This
  809. means background pixels (color value 0) are black by default, while
  810. foreground pixels (color value 1) are white.
  811.  
  812.      The 18-bit video DAC values consist of three 6-bit red, green, and blue
  813. color components.  Hence, each color component is an integer between 0 and
  814. 63; increasing values produce more intense colors.  The default color
  815. components for DAC register 0 are red=0, blue=0, and green=0, which produces
  816. black.  The default values for the other DAC registers are red=63, blue=63,
  817. and green=63, which produces white.  Because the video DAC registers are 18
  818. bits long, each DAC can specify one of 262,144 (218) colors.  However,
  819. because the palette registers hold 1-bit quantities, only two of these colors
  820. can be displayed at the same time.  In other words, mode 17 provides the
  821. capability of displaying two simultaneous colors from a group of 262,144.
  822. 82   Fastgraph User's Guide
  823.  
  824.  
  825.      In mode 17, the fg_setcolor routine defines the current color by
  826. referencing one of the two palette registers.  The fg_palette routine defines
  827. the value of a palette register by referencing one of the 16 video DAC
  828. registers.  That is, the fg_palette routine specifies the video DAC register
  829. that a palette register references.  The first argument of the fg_palette
  830. routine is either 0 or 1 and specifies the palette number.  The second
  831. argument is an integer between 0 and 15 that specifies the video DAC register
  832. for that palette.
  833.  
  834.      The Fastgraph routine fg_setrgb defines the value of a video DAC
  835. register in mode 17.  The first argument of the fg_setrgb routine is an
  836. integer between 0 and 15 that specifies the DAC register number.  The
  837. remaining three arguments are each integer values between 0 and 63 that
  838. respectively specify the red, green, and blue color components for that DAC
  839. register.
  840.  
  841.      Example 5-9 demonstrates the use of the fg_palette, fg_setrgb, and
  842. fg_setcolor routines in mode 17.  After establishing the video mode, the
  843. program defines DAC register 0 to be blue (red=0, green=0, blue=42) and DAC
  844. register 1 to be yellow (red=63, green=63, blue=21).  Note that defining DAC
  845. register 0 changes the background color because palette 0 references DAC
  846. register 0.  The program then makes color 1 the current color (palette 1
  847. still references DAC register 1) and displays the word "Hello" in yellow.
  848. After waiting for a keystroke, the program changes the color of "Hello" by
  849. making palette 1 reference DAC register 15 (which still contains its default
  850. value, white).  Finally, it restores the original video mode and screen
  851. attributes before returning to DOS.
  852.  
  853.                                  Example 5-9.
  854.  
  855.                           #include <fastgraf.h>
  856.                           void main(void);
  857.  
  858.                           void main()
  859.                           {
  860.                              int mode;
  861.  
  862.                              mode = fg_getmode();
  863.                              fg_setmode(17);
  864.  
  865.                              fg_setrgb(0,0,0,42);
  866.                              fg_setrgb(1,63,63,21);
  867.  
  868.                              fg_setcolor(1);
  869.                              fg_text("Hello",5);
  870.                              fg_waitkey();
  871.  
  872.                              fg_palette(1,15);
  873.                              fg_waitkey();
  874.  
  875.                              fg_setmode(mode);
  876.                              fg_reset();
  877.                           }
  878.  
  879.                                              Chapter 5:  The Use of Color   83
  880.  
  881.  
  882.  
  883. VGA/SVGA 16-Color Modes
  884.  
  885.      The VGA and SVGA 16-color modes (modes 18, 28, and 29) have 16 color
  886. values, numbered 0 to 15.  Each color value references one of 16 user-
  887. definable palette registers, often simply called palettes, also numbered 0 to
  888. 15.  Each palette register in turn references one of 16 user-definable 18-bit
  889. video DAC registers, also numbered 0 to 15.  The values assigned to the
  890. palette registers and video DAC registers determine the colors in which
  891. pixels are displayed.  For example, if palette register 1 contains the value
  892. 3, and video DAC register 3 contains the color value for red, then pixels
  893. whose color value is 1 will be red.
  894.  
  895.      By default, each of the 16 palette registers references the video DAC
  896. register of the same number.  In addition, the 16 video DAC registers
  897. respectively contain the color values for the 16 colors in the standard color
  898. set.
  899.  
  900.      The 18-bit video DAC values consist of three 6-bit red, green, and blue
  901. color components.  Hence, each color component is an integer between 0 and
  902. 63; increasing values produce more intense colors.  The default RGB color
  903. components for the 16 video DAC registers are:
  904.  
  905.      DAC  R  G  B   color     DAC  R  G  B   color
  906.  
  907.       0   0  0  0   black      8  21 21 21   dark gray
  908.       1   0  0 42   blue       9  21 21 63   light blue
  909.       2   0 42  0   green     10  21 63 21   light green
  910.       3   0 42 42   cyan      11  21 63 63   light cyan
  911.       4  42  0  0   red       12  63 21 21   light red
  912.       5  42  0 42   magenta   13  63 21 63   light magenta
  913.       6  42 21  0   brown     14  63 63 21   yellow
  914.       7  42 42 42   gray      15  63 63 63   white
  915.  
  916. Because the video DAC registers are 18 bits long, each DAC can specify one of
  917. 262,144 (218) colors.  However, because the palette registers hold 4-bit
  918. quantities, only 16 of these colors can be displayed at the same time.  In
  919. other words, mode 18 provides the capability of displaying 16 simultaneous
  920. colors from a group of 262,144.
  921.  
  922.      In the 16-color VGA and SVGA modes, the fg_setcolor, fg_palette, and
  923. fg_setrgb routines function exactly as in mode 17 with one exception:  there
  924. are 16 palette registers instead of just two.  Example 5-9 demonstrates the
  925. use of these routines in mode 17, but it also would work in mode 18, 28, or
  926. 29 if the call to fg_setmode were changed accordingly.
  927.  
  928.  
  929. 256-Color Modes
  930.  
  931.      The 256-color modes (modes 19 through 27) have 256 color values,
  932. numbered 0 to 255.  Each color value directly references one of 256 user-
  933. definable 18-bit video DAC registers, also numbered 0 to 255.  The values
  934. assigned to the video DAC registers determine the colors in which pixels are
  935. displayed.  For example, if video DAC register 3 contains the color value for
  936. red, then pixels whose color value is 3 will be red.
  937. 84   Fastgraph User's Guide
  938.  
  939.  
  940.      By default, the first 16 video DAC registers (0 to 15) contain the color
  941. values for the standard color set.  The next 16 DAC registers (16 to 31)
  942. contain the color values for a gray scale of gradually increasing intensity.
  943. The next 216 DAC registers (32 to 247) contain three groups of 72 colors
  944. each, with the first group (32 to 103) at high intensity, the second group
  945. (104 to 175) at moderate intensity, and the third group (176 to 247) at low
  946. intensity.  Each group consists of three ranges of decreasing saturation
  947. (increasing whiteness), with each range varying in hue from blue to red to
  948. green.  Finally, the last 8 DAC registers (248 to 255) alternate between
  949. black and white.  This information is summarized in the following table.
  950.  
  951.           DACs        default color values
  952.  
  953.           0 to 15     standard color set
  954.           16 to 31    gray scale of gradually increasing intensity
  955.           32 to 55    high saturation, high intensity colors
  956.           56 to 79    moderate saturation, high intensity colors
  957.           80 to 103   low saturation, high intensity colors
  958.           104 to 127  high saturation, moderate intensity colors
  959.           128 to 151  moderate saturation, moderate intensity colors
  960.           152 to 175  low saturation, moderate intensity colors
  961.           176 to 199  high saturation, low intensity colors
  962.           200 to 223  moderate saturation, low intensity colors
  963.           224 to 247  low saturation, low intensity colors
  964.           248 to 255  alternate between black and white
  965.  
  966.      The 18-bit video DAC values consist of three 6-bit red, green, and blue
  967. color components.  Hence, each color component is an integer between 0 and
  968. 63; increasing values produce more intense colors.  Because the video DAC
  969. registers are 18 bits long, each DAC can specify one of 262,144 (218) colors.
  970. However, because the color values are 8-bit quantities, only 256 of these
  971. colors can be displayed at the same time.  In other words, modes 19 through
  972. 27 provide the capability of displaying 256 simultaneous colors from a group
  973. of 262,144.
  974.  
  975.      In the 256-color graphics modes, the fg_setcolor routine defines the
  976. current color by referencing on of the 256 video DAC registers.  The
  977. fg_setrgb routine defines the actual color of a video DAC register.  The
  978. first argument of the fg_setrgb routine is an integer between 0 and 255 that
  979. specifies the DAC register number.  The remaining three arguments are each
  980. integer values between 0 and 63 that respectively specify the red, green, and
  981. blue color components for that DAC register.  Another Fastgraph routine,
  982. fg_getrgb, returns the color components for a specified DAC register.  Its
  983. arguments are the same as for fg_setrgb, except the last three arguments (the
  984. return values) are passed by reference rather than by value.
  985.  
  986.      You also can use the Fastgraph routine fg_palette to define the value of
  987. a video DAC register in modes 19 through 27.  The first argument of the
  988. fg_palette routine is an integer between 0 and 255 that specifies the DAC
  989. register number.  The second argument is an integer between 0 and 63 that
  990. specifies the color value for that video DAC register, using the same 64
  991. values as in the EGA enhanced mode (mode 16).
  992.  
  993.      Example 5-10 demonstrates the use of the fg_setcolor routine in mode 19.
  994. The program uses the Fastgraph routine fg_rect to draw vertical lines.  After
  995. establishing the video mode, the program uses a for loop to draw 256 vertical
  996.                                              Chapter 5:  The Use of Color   85
  997.  
  998.  
  999. lines, one in each of the 256 colors (using the default DAC values).
  1000. Finally, the program restores the original video mode and screen attributes
  1001. before returning to DOS.
  1002.  
  1003.                                 Example 5-10.
  1004.  
  1005.                 #include <fastgraf.h>
  1006.                 void main(void);
  1007.  
  1008.                 #define COLORS 256
  1009.  
  1010.                 void main()
  1011.                 {
  1012.                    int base;
  1013.                    int color;
  1014.                    int mode;
  1015.                    int x;
  1016.  
  1017.                    mode = fg_getmode();
  1018.                    fg_setmode(19);
  1019.  
  1020.                    x = 0;
  1021.  
  1022.                    for (color = 0; color < COLORS; color++) {
  1023.                       fg_setcolor(color);
  1024.                       fg_rect(x,x,0,199);
  1025.                       x++;
  1026.                       }
  1027.                    fg_waitkey();
  1028.  
  1029.                    fg_setmode(mode);
  1030.                    fg_reset();
  1031.                 }
  1032.  
  1033.      Example 5-11 shows an interesting effect available in video modes that
  1034. support DAC registers.  The program uses the Fastgraph routine fg_waitfor
  1035. (discussed in Chapter 16) to delay the program's execution.  After
  1036. establishing the video mode, the program displays the word "Hello" in color
  1037. 103, which by default is a pastel blue.  It then uses routine fg_getrgb to
  1038. retrieve the color components for this color.  The while loop gradually
  1039. decreases the color components until all three components are zero, which
  1040. makes the word "Hello" smoothly fade to black.  Finally, the program restores
  1041. the original video mode and screen attributes before returning to DOS.
  1042.  
  1043.                                 Example 5-11.
  1044.  
  1045.                      #include <fastgraf.h>
  1046.                      void main(void);
  1047.  
  1048.                      void main()
  1049.                      {
  1050.                         int old_mode;
  1051.                         int red, green, blue;
  1052.  
  1053.                         old_mode = fg_getmode();
  1054.                         fg_setmode(19);
  1055. 86   Fastgraph User's Guide
  1056.  
  1057.  
  1058.                         fg_setcolor(103);
  1059.                         fg_text("Hello",5);
  1060.                         fg_waitfor(18);
  1061.  
  1062.                         fg_getrgb(103,&red,&green,&blue);
  1063.  
  1064.                         while (red+green+blue > 0) {
  1065.                            if (red > 0) red--;
  1066.                            if (green > 0) green--;
  1067.                            if (blue > 0) blue--;
  1068.                            fg_setrgb(103,red,green,blue);
  1069.                            fg_waitfor(1);
  1070.                            }
  1071.  
  1072.                         fg_setmode(old_mode);
  1073.                         fg_reset();
  1074.                      }
  1075.  
  1076.      The fg_setrgb and fg_getrgb routines work with individual DAC registers.
  1077. If you want to define or retrieve a block of consecutive DAC registers, using
  1078. the fg_setdacs and fg_getdacs routines is more efficient.  The fg_setdacs
  1079. routine defines the values of a block of contiguous DAC registers.  Its first
  1080. argument is the index of the first DAC register to define (between 0 and
  1081. 255), and its second argument is the number of DAC registers to define
  1082. (between 1 and 256).  The third argument is a byte array containing the RGB
  1083. color components for the DAC registers being defined.  The array's first
  1084. three bytes contain the red, green, and blue components for the first DAC,
  1085. the next three for the second DAC, and so forth.  The size of this array must
  1086. be at least three times the value of the second argument.  The fg_getdacs
  1087. arguments are the same as those for fg_setdacs, but the RGB array instead
  1088. receives the current values of the specified DAC registers.  Both routines
  1089. treat the DAC register numbers in a circular fashion (for example, defining
  1090. four DACs starting with number 254 will define DACs 254, 255, 0, and 1).
  1091.  
  1092.      Example 5-12 is similar to example 5-11, but it fades many colors
  1093. simultaneously.  The program displays seven asterisks, one each in colors 9
  1094. through 15.  It uses fg_getdacs to obtain the current settings of the
  1095. corresponding DAC registers; these values are stored in the array RGBvalues.
  1096. The while loop gradually fades the RGB components to zero, using fg_setdacs
  1097. to update their values, similar to the method of example 5-11.  This
  1098. illustrates an attractive way of turning an image into a blank screen.
  1099.  
  1100.                                 Example 5-12.
  1101.  
  1102.                        #include <fastgraf.h>
  1103.                        void main(void);
  1104.  
  1105.                        void main()
  1106.                        {
  1107.                           int decreasing;
  1108.                           int i;
  1109.                           int old_mode;
  1110.                           char RGBvalues[21];
  1111.  
  1112.                           old_mode = fg_getmode();
  1113.                           fg_setmode(19);
  1114.                                              Chapter 5:  The Use of Color   87
  1115.  
  1116.  
  1117.  
  1118.                           for (i = 9; i <= 15; i++) {
  1119.                              fg_setcolor(i);
  1120.                              fg_text("*",1);
  1121.                              }
  1122.  
  1123.                           fg_getdacs(9,7,RGBvalues);
  1124.                           fg_waitfor(18);
  1125.  
  1126.                           do {
  1127.                              decreasing = 0;
  1128.                              for (i = 0; i < 21; i++)
  1129.                                 if (RGBvalues[i] > 0) {
  1130.                                    RGBvalues[i]--;
  1131.                                    decreasing = 1;
  1132.                                    }
  1133.                              fg_setdacs(9,7,RGBvalues);
  1134.                              fg_waitfor(1);
  1135.                              }
  1136.                           while (decreasing);
  1137.  
  1138.                           fg_setmode(old_mode);
  1139.                           fg_reset();
  1140.                        }
  1141.  
  1142. Note that examples 5-11 and 5-12 also would work in 16-color VGA and SVGA
  1143. video modes as long as you just use the first 16 video DAC registers.
  1144.  
  1145.  
  1146. Using Video DAC Registers in EGA Modes
  1147.  
  1148.      The fg_getdacs and fg_setdacs routines also work in modes 13, 14, and 16
  1149. when used on a VGA or SVGA system.  This lets you choose 16 colors from a
  1150. palette of 262,144 colors, just as in mode 18.  If you attempt to use these
  1151. routines on an EGA system, the results are unpredictable.  Applications that
  1152. use these routines should therefore first verify they are running on a VGA or
  1153. SVGA system by checking if fg_testmode(18,0) returns a nonzero value.
  1154.  
  1155.      Before attempting to use fg_getdacs and fg_setdacs in modes 13, 14, and
  1156. 16, you should first be aware of the relationship between VGA palettes and
  1157. DAC registers.  On the EGA, palette values directly determine the color
  1158. displayed.  On the VGA and SVGA, however, there is an added level of
  1159. indirection.  VGA and SVGA palette registers can be thought of as pointers to
  1160. video DAC registers whose RGB components determine the displayed color.
  1161.  
  1162.      Each palette register in the VGA 640 by 480 16-color graphics mode (mode
  1163. 18) initially points to the DAC register of the same number.  We can thus
  1164. pretend the indirection does not exist because changing DAC register n
  1165. affects those pixels whose color value is n (unless, of course, we've changed
  1166. the value of palette register n).  In modes 13, 14, and 16, we can't ignore
  1167. the indirection because the palette registers contain different values.  In
  1168. mode 13, for instance, palette register 8 contains the value 16 by default,
  1169. not the value 8 as in mode 18.
  1170.  
  1171.      The easiest way around this inconsistency is to explicitly set the
  1172. palette and DAC registers so they correspond to the default values of mode
  1173. 88   Fastgraph User's Guide
  1174.  
  1175.  
  1176. 18.  There are two cases to consider -- one for modes 13 and 14, and the
  1177. other for mode 16.
  1178.  
  1179.      In modes 13 and 14, palettes 0 to 7 contain the values 0 to 7, but
  1180. palettes 8 to 15 contain the values 16 to 23.  Hence, if you want to use
  1181. fg_getdacs and fg_setdacs in these modes, you should include the following
  1182. code after calling fg_setmode.
  1183.  
  1184.  
  1185.                        char RGBvalues[3];
  1186.                        int i;
  1187.  
  1188.                        for (i = 8; i < 16; i++) {
  1189.                           fg_getdacs(i+8,1,RGBvalues);
  1190.                           fg_setdacs(i,1,RGBvalues);
  1191.                           fg_palette(i,i);
  1192.                        }
  1193.  
  1194.  
  1195. This code will set the values of DACs 8 to 15 to the values of DACs 16 to 23.
  1196. It also sets palettes 8 to 15 to point to DACs 8 to 15.  You can then ignore
  1197. the palette-DAC indirection because setting DAC register n affects pixels of
  1198. color n.
  1199.  
  1200.      In mode 16, palette 6 is initially assigned the value 20, and palettes 8
  1201. to 15 are assigned the values 56 to 63.  All other palettes point to the DAC
  1202. of the same number.  Hence, if you want to use fg_getdacs and fg_setdacs in
  1203. mode 16, you should include the following code after calling fg_setmode.
  1204.  
  1205.  
  1206.                        char RGBvalues[3];
  1207.                        int i;
  1208.  
  1209.                        fg_getdacs(20,1,RGBvalues);
  1210.                        fg_setdacs(6,1,RGBvalues);
  1211.                        fg_palette(6,6);
  1212.  
  1213.                        for (i = 8; i < 16; i++) {
  1214.                           fg_getdacs(i+48,1,RGBvalues);
  1215.                           fg_setdacs(i,1,RGBvalues);
  1216.                           fg_palette(i,i);
  1217.                        }
  1218.  
  1219.  
  1220. This code will set the values of DAC 6 to the values of DAC 20, and also DACs
  1221. 8 to 15 to the values of DACs 56 to 63.  It also sets palettes 6 and 8-15 to
  1222. point to the identically-numbered DACs.  You can then ignore the palette-DAC
  1223. indirection because setting DAC register n affects pixels of color n.
  1224.  
  1225.      While this might all seem complicated at first, it really isn't once you
  1226. understand the relationship between palettes and DACs.  The ability to select
  1227. colors from a palette of 256K colors instead of 16 or 64 is usually well
  1228. worth the extra effort.
  1229.                                              Chapter 5:  The Use of Color   89
  1230.  
  1231.  
  1232.  
  1233. RGB Color Mapping
  1234.  
  1235.      If you're developing an application that runs in 256-color and 16-color
  1236. graphics modes, you've probably noticed the inherent differences in defining
  1237. color values.  In fact, the palette register values even use different
  1238. structures within the various 16-color modes.  The Fastgraph routine
  1239. fg_maprgb helps simplify these differences.  It maps three RGB color
  1240. components (each between 0 and 63) into a 16-color palette value suitable for
  1241. the current video mode.  Of course, the range of available colors is much
  1242. more restricted in the 16-color modes than in the 256-color modes, so
  1243. fg_maprgb must map the RGB components into the closest available color.
  1244.  
  1245.      Example 5-13 runs in any 16-color or 256-color graphics mode and
  1246. demonstrates the use of the fg_maprgb routine.  In 256-color modes, the
  1247. program simply uses fg_setrgb to define DAC register 1 to a pastel blue
  1248. (red=45, green=49, blue=63).  In 16-color modes, however, the program calls
  1249. fg_maprgb to convert the color components into a palette value in IRGB,
  1250. IxRGB, or rgbRGB format (depending on the current video mode).  The fg_maprgb
  1251. return value is passed to fg_palette to set palette register 1 to the closest
  1252. available color defined by the specified RGB components.
  1253.  
  1254.                                 Example 5-13.
  1255.  
  1256.           #include <fastgraf.h>
  1257.           #include <stdio.h>
  1258.           #include <stdlib.h>
  1259.           void main(void);
  1260.  
  1261.           void main()
  1262.           {
  1263.              int new_mode, old_mode;
  1264.  
  1265.              new_mode = fg_bestmode(320,200,1);
  1266.              if (new_mode < 0 || new_mode == 4 || new_mode == 12) {
  1267.                 printf("This program requires a 320 x 200 ");
  1268.                 printf("16-color or 256-color graphics mode.\n");
  1269.                 exit(1);
  1270.                 }
  1271.              old_mode = fg_getmode();
  1272.              fg_setmode(new_mode);
  1273.  
  1274.              fg_setcolor(1);
  1275.              if (new_mode <= 16)
  1276.                 fg_palette(1,fg_maprgb(45,49,63));
  1277.              else
  1278.                 fg_setrgb(1,45,49,63);
  1279.              fg_text("Hello",5);
  1280.              fg_waitkey();
  1281.  
  1282.              fg_setmode(old_mode);
  1283.              fg_reset();
  1284.           }
  1285.  
  1286. 90   Fastgraph User's Guide
  1287.  
  1288.  
  1289.  
  1290. Defining All Palette Registers
  1291.  
  1292.      Fastgraph includes a routine fg_palettes that defines all 16 palette
  1293. registers in 16-color graphics modes.  You also can use the fg_palettes
  1294. routine to define the first 16 video DAC registers in 256-color modes.  It
  1295. has no effect in other video modes.
  1296.  
  1297.      Using fg_palettes is much faster than calling the fg_palette routine 16
  1298. times.  The argument to the fg_palettes routine is a 16-element integer array
  1299. that contains the color values assigned respectively to palette registers (or
  1300. video DAC registers) 0 to 15.  Example 5-14 demonstrates how to zero the
  1301. palette registers (that is, change them all to black) in mode 13.
  1302.  
  1303.                                 Example 5-14.
  1304.  
  1305.               #include <fastgraf.h>
  1306.               void main(void);
  1307.  
  1308.               int zeroes[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  1309.  
  1310.               void main()
  1311.               {
  1312.                  int mode;
  1313.  
  1314.                  mode = fg_getmode();
  1315.                  fg_setmode(13);
  1316.  
  1317.                  fg_palettes(zeroes);
  1318.  
  1319.                  fg_setmode(mode);
  1320.                  fg_reset();
  1321.               }
  1322.  
  1323. Of course, as this example is written, it appears to do nothing more than
  1324. blank the screen.  Its purpose is to show an example of the fg_palettes
  1325. routine.
  1326.  
  1327.  
  1328. Virtual Colors
  1329.  
  1330.      By this time it should be clear the use of color is rather specific to
  1331. each graphics video mode.  One of the most obvious differences is the number
  1332. of available colors in each mode; it ranges from 2 to 256.  By available
  1333. colors, we mean the number of colors that can be displayed simultaneously.
  1334.  
  1335.      To simplify programming in graphics modes, Fastgraph provides 256
  1336. virtual colors.  The virtual colors are used in the graphics video modes
  1337. having fewer than 256 available colors.  Virtual colors allow you to use 256
  1338. color indices in all graphics modes, even if a particular mode does not have
  1339. 256 available colors.
  1340.  
  1341.      When you establish a video mode with the fg_setmode routine, Fastgraph
  1342. initializes all the virtual color indices.  It does this by replicating the
  1343. video mode's color values through the 256 virtual color indices.  For
  1344. example, the CGA color modes (4 and 5) have four color values, numbered 0
  1345.                                              Chapter 5:  The Use of Color   91
  1346.  
  1347.  
  1348. through 3.  In these modes, the fg_setmode routine initializes color indices
  1349. 0, 4, 8, ... , 252 to 0; color indices 1, 5, 9, ... , 253 to 1; color indices
  1350. 2, 6, 10, ... , 254 to 2; and color indices 3, 7, 11, ... , 255 to 3.
  1351. Similarly, in 16-color graphics modes the color indices 0, 16, 32, ... , 240
  1352. are set to 0, and so forth.  In the monochrome EGA graphics video mode (mode
  1353. 15), the color values are numbered 0, 1, 4, and 5, so fg_setmode replicates
  1354. the color indices in groups of eight, even though there are only four
  1355. available colors.  An analysis of the color value sequences reveals an often
  1356. useful feature:  by default, virtual color 0 is black and virtual colors 15
  1357. and 255 are white in all graphics video modes.
  1358.  
  1359.      It is thus possible to write a multiple-mode program using the same
  1360. color indices for each graphics mode.  For example, a program that contains
  1361. the statement fg_setcolor(5) would produce subsequent graphics in color 5
  1362. (magenta by default) when running in a 16-color graphics mode.  It would
  1363. produce subsequent graphics in color 1 (light cyan by default) when running
  1364. in a CGA color mode.  This is because 1 is the default value assigned to
  1365. virtual color index 5 in the CGA color modes.
  1366.  
  1367.      The fg_setmode routine establishes default values for the 256 virtual
  1368. color indices, but it might be desirable to assign other available colors to
  1369. them.  Going back to the discussion in the previous paragraph, color number 2
  1370. is light magenta in the default CGA mode 4 palette.  It might make more sense
  1371. if the color value 2 were assigned to virtual color index 5, as this would
  1372. make the graphics drawn in color 5 the same color in mode 4 as in other color
  1373. modes.  The Fastgraph routine fg_defcolor is provided for this purpose.
  1374.  
  1375.      The fg_defcolor routine assigns a color value to a virtual color index.
  1376. It has two arguments:  the first specifies the virtual color index (between 0
  1377. and 255), and the second specifies the color value (between 0 and one less
  1378. than the number of available colors in the current video mode).  For example,
  1379. the statement
  1380.  
  1381.                               fg_defcolor(5,2);
  1382.  
  1383. would assign the color value 2 to the color index 5.  Another Fastgraph
  1384. routine, fg_getindex, returns the current value assigned to a specified color
  1385. index.  After executing the above call to fg_defcolor, the statement
  1386.  
  1387.                            color = fg_getindex(5);
  1388.  
  1389. would store the value 2 (the current value of color index 5) in the integer
  1390. variable color.
  1391.  
  1392.      It is important to understand the difference between virtual colors and
  1393. palette registers.  Modifying the value of a palette register changes the
  1394. color of all pixels already drawn using that palette.  Modifying a virtual
  1395. color index does not do this; it only specifies any graphics drawn in that
  1396. color from this point on will appear in the new color.
  1397.  
  1398.      Example 5-15 demonstrates virtual colors in mode 4.  After establishing
  1399. the video mode, the program uses fg_defcolor to define virtual color indices
  1400. 0 and 255 to be 1, which by default is light cyan in mode 4.  It then draws
  1401. characters using color indices 0, 1, and 255, and in each case the characters
  1402. appear in light cyan.  Finally, the program restores the original video mode
  1403. and screen attributes before returning to DOS.
  1404. 92   Fastgraph User's Guide
  1405.  
  1406.  
  1407.                                 Example 5-15.
  1408.  
  1409.                            #include <fastgraf.h>
  1410.                            void main(void);
  1411.  
  1412.                            void main()
  1413.                            {
  1414.                               int mode;
  1415.  
  1416.                               mode = fg_getmode();
  1417.                               fg_setmode(4);
  1418.  
  1419.                               fg_defcolor(0,1);
  1420.                               fg_defcolor(255,1);
  1421.  
  1422.                               fg_setcolor(0);
  1423.                               fg_text("0",1);
  1424.                               fg_setcolor(1);
  1425.                               fg_text(" 1",2);
  1426.                               fg_setcolor(255);
  1427.                               fg_text(" 255",4);
  1428.                               fg_waitkey();
  1429.  
  1430.                               fg_setmode(mode);
  1431.                               fg_reset();
  1432.                            }
  1433.  
  1434.  
  1435. A Multiple-Mode Example
  1436.  
  1437.      Even though the color capabilities differ between the supported video
  1438. modes, Fastgraph makes it easy to write a program that runs in many video
  1439. modes.  This section will present an example of such a program.
  1440.  
  1441.      Example 5-16 illustrates a program that will run in any of Fastgraph's
  1442. supported video modes.  The program first asks for the video mode number,
  1443. checks if the mode number is valid, and then checks if the requested mode is
  1444. available on the user's system.  After doing this, the program establishes
  1445. the video mode and performs its mode-specific code.  It then displays a brief
  1446. message that includes the video mode number in which the program is running.
  1447. This information remains on the screen until a key is pressed, at which time
  1448. the program restores the original video mode and screen attributes before
  1449. returning to DOS.
  1450.  
  1451.                                 Example 5-16.
  1452.  
  1453.        #include <fastgraf.h>
  1454.        #include <stdio.h>
  1455.        #include <stdlib.h>
  1456.        void main(void);
  1457.  
  1458.        void main()
  1459.        {
  1460.           int mode, old_mode;
  1461.           char string[5];
  1462.  
  1463.                                              Chapter 5:  The Use of Color   93
  1464.  
  1465.        /* Ask for the video mode number */
  1466.           printf("Which video mode? ");
  1467.           scanf("%d",&mode);
  1468.  
  1469.        /* Make sure the entered value is valid */
  1470.           if (mode < 0 || mode > 29) {
  1471.              printf("%d is not a valid video mode number.\n",mode);
  1472.              exit(1);
  1473.              }
  1474.  
  1475.        /* Make sure the requested video mode is available */
  1476.           if (fg_testmode(mode,1) == 0) {
  1477.              printf("Mode %d is not available on this system.\n",mode);
  1478.              exit(1);
  1479.              }
  1480.  
  1481.        /* Establish the video mode */
  1482.           old_mode = fg_getmode();
  1483.           fg_setmode(mode);
  1484.  
  1485.        /* Perform mode-specific initializations */
  1486.           if (mode <= 3 || mode == 7)   /* text modes */
  1487.              fg_cursor(0);
  1488.  
  1489.           else if (mode == 4 || mode == 5) { /* CGA color modes */
  1490.              fg_palette(0,0);
  1491.              fg_defcolor(14,3);
  1492.              }
  1493.  
  1494.           else if (mode == 6) {         /* CGA two-color mode */
  1495.              fg_palette(0,14);
  1496.              fg_defcolor(14,1);
  1497.              }
  1498.  
  1499.           else if (mode == 11)          /* Hercules mode */
  1500.              fg_defcolor(14,1);
  1501.  
  1502.           else if (mode == 12)          /* Hercules low-res mode */
  1503.              fg_defcolor(14,3);
  1504.  
  1505.           else if (mode == 17) {        /* VGA two-color mode */
  1506.              fg_palette(1,14);
  1507.              fg_setrgb(14,63,63,21);
  1508.              fg_defcolor(14,1);
  1509.              }
  1510.  
  1511.        /* Display a message that includes the video mode number */
  1512.           fg_setcolor(14);
  1513.           fg_text("I'm running in mode ",20);
  1514.           sprintf(string,"%d. ",mode);
  1515.           fg_text(string,3);
  1516.  
  1517.        /* Wait for a keystroke */
  1518.           fg_waitkey();
  1519.  
  1520.        /* Restore the original video mode and screen attributes */
  1521.           fg_setmode(old_mode);
  1522. 94   Fastgraph User's Guide
  1523.  
  1524.  
  1525.           fg_reset();
  1526.        }
  1527.  
  1528.  
  1529.      Example 5-16 displays its message in yellow for those video modes that
  1530. offer color.  In monochrome video modes, it displays the message in normal
  1531. intensity.  The program uses virtual color 14, which by default is yellow in
  1532. many video modes; the mode-specific code in example 5-16 makes color 14
  1533. yellow in other video modes.  In text video modes (modes 0 to 3 and 7), the
  1534. program uses the fg_cursor routine to make the cursor invisible.  In CGA
  1535. color modes (modes 4 and 5), the program uses the fg_palette routine to
  1536. select a CGA palette that contains yellow as color 3 and then uses
  1537. fg_defcolor to assign color 3 to virtual color 14.  In CGA two-color mode
  1538. (mode 6), the program uses the fg_palette routine to make color 1 yellow and
  1539. then uses fg_defcolor to assign color 1 to virtual color 14.  In the Hercules
  1540. modes (modes 11 and 12), the program uses the fg_defcolor routine to assign
  1541. the value for normal intensity pixels to color 14.  In VGA two-color mode
  1542. (mode 17), the program uses the fg_palette routine to assign video DAC
  1543. register 14 to palette register 1.  It then defines video DAC register 14 to
  1544. be yellow with the fg_setrgb routine and finally uses fg_defcolor to assign
  1545. color 1 (that is, palette register 1) to virtual color 14.  In all other
  1546. video modes, color 14 is yellow by default.
  1547.  
  1548.  
  1549. Summary of Color-Related Routines
  1550.  
  1551.      This section summarizes the functional descriptions of the Fastgraph
  1552. routines presented in this chapter.  More detailed information about these
  1553. routines, including their arguments and return values, may be found in the
  1554. Fastgraph Reference Manual.
  1555.  
  1556.      FG_DEFCOLOR assigns a color value to a virtual color index.  This
  1557. routine is only meaningful in the graphics video modes that have fewer than
  1558. 256 available colors.
  1559.  
  1560.      FG_GETCOLOR returns the current text attribute (in text modes) or color
  1561. index (in graphics modes), as specified in the most recent call to fg_setattr
  1562. or fg_setcolor.
  1563.  
  1564.      FG_GETDACS retrieves the red, green, and blue color components for a
  1565. block of consecutively numbered video DAC registers.  This routine is only
  1566. meaningful modes that use DAC registers.
  1567.  
  1568.      FG_GETINDEX returns the color value assigned to a specified virtual
  1569. color index.  In text modes and in graphics modes that have 256 available
  1570. colors, this routine returns the value passed to it.
  1571.  
  1572.      FG_GETRGB returns the red, green, and blue color components for a
  1573. specified video DAC register.  This routine is only meaningful in modes that
  1574. use DAC registers.
  1575.  
  1576.       FG_MAPRGB maps six-bit red, green, and blue color components into a
  1577. suitable palette value for the current video mode.  You can then pass this
  1578. value to the fg_palette routine.  This routine is meaningful only in 16-color
  1579. graphics video modes.
  1580.                                              Chapter 5:  The Use of Color   95
  1581.  
  1582.  
  1583.      FG_PALETTE has different functions depending on the current graphics
  1584. video mode.  For the CGA four-color modes, it establishes the current palette
  1585. (of six available) and defines the background color for that palette.  In the
  1586. CGA two-color mode, it defines the foreground color.  For the Tandy/PCjr,
  1587. EGA, and VGA graphics modes, it defines the value of a single palette
  1588. register.  For 256-color graphics modes, it defines the value of a single
  1589. video DAC register.  The fg_palette routine has no effect in text modes or
  1590. Hercules graphics modes.
  1591.  
  1592.      FG_PALETTES defines all 16 palette registers (in 16-color graphics
  1593. modes), or the first 16 video DAC registers (in 256-color graphics modes).
  1594. The fg_palettes routine has no effect in text modes, CGA graphics modes, or
  1595. Hercules graphics modes.
  1596.  
  1597.      FG_SETATTR establishes the current text attribute in text video modes.
  1598. This routine has no effect in graphics modes.
  1599.  
  1600.      FG_SETCOLOR establishes the current color index (which may be a virtual
  1601. color index in graphics modes).  In text modes, the fg_setcolor routine
  1602. provides an alternate method of establishing the current text attribute.
  1603.  
  1604.      FG_SETDACS defines the values of a block of consecutively numbered video
  1605. DAC registers by specifying their red, green, and blue color components.
  1606. This routine is only meaningful in modes that use DAC registers.
  1607.  
  1608.      FG_SETRGB defines the value of a single palette register (in Tandy/PCjr
  1609. and EGA graphics modes) or video DAC register (in VGA, MCGA, and SVGA modes)
  1610. by specifying its red, green, and blue color components.  The fg_setrgb
  1611. routine has no effect in text modes, CGA graphics modes, or Hercules graphics
  1612. modes.
  1613. 96   Fastgraph User's Guide
  1614.